package com.example.springel.el;

import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

/**
 * el解析
 *
 * @author xiaoshitou
 * @date 2021/09/24
 */
public class ElParse {

    static class ElFunc {

        /**
         * 基数
         *
         * @param num
         * @return boolean
         */
        public boolean cardinalNumber(int num) {
            return num % 2 == 1;
        }

        /**
         * 注意 eq 是关键字
         * @param num
         * @return
         */
        public boolean eqs(int num) {
            return num == 1;
        }
    }

    /**
     * 2. 调用方法 方法注册到 context 中
     *
     * @return {@link ElParse}
     */
    public ElParse get() {
        // 解释器
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(new ElFunc());
        // 设置内容
        Expression expression = spelExpressionParser.parseExpression("cardinalNumber(2)");
        Object value = expression.getValue(standardEvaluationContext);
        System.out.println("cardinalNumber(2): " + value);
        return this;
    }

    /**
     * 添加和bean上下文
     * @beanName.func 调用上下文内容
     * bean context + el context
     *
     * @param num
     * @return {@link ElParse}
     */
    public ElParse addGetAndBeanContext(int num) {
        StaticApplicationContext applicationContext = new StaticApplicationContext();
        applicationContext.registerSingleton("elFunc", ElFunc.class);

        // 解释器
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(new ElFunc());
        standardEvaluationContext.setBeanResolver(new BeanFactoryResolver(applicationContext));

        // 设置上下文内容, 使 el 可以获取占位符内容
        standardEvaluationContext.setVariable("num", num);
        // 设置内容
        Expression expression = spelExpressionParser.parseExpression("@elFunc.cardinalNumber(#num)");
        Object value = expression.getValue(standardEvaluationContext);
        System.out.println("@elFunc.cardinalNumber(#num): " + value);
        return this;
    }


    /**
     * 从 el context 中读取数据
     * @param num
     * @return
     */
    public ElParse addGet(int num) {
        // 解释器
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(new ElFunc());
        // 设置上下文内容, 使 el 可以获取占位符内容
        standardEvaluationContext.setVariable("num", num);
        // 设置内容
        Expression expression = spelExpressionParser.parseExpression("cardinalNumber(#num)");
        Object value = expression.getValue(standardEvaluationContext);
        System.out.println("cardinalNumber(#num): " + value);
        return this;
    }

    /**
     * 1. 简单
     * @return
     */
    public ElParse add() {
        // 解释器
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        // 设置内容
        Expression expression = spelExpressionParser.parseExpression("1 + 1");
        Object value = expression.getValue();
        System.out.println("1 + 1: " + value);
        return this;
    }

    public ElParse eqAndBeanContext(int num) {
        StaticApplicationContext applicationContext = new StaticApplicationContext();
        applicationContext.registerSingleton("elFunc", ElFunc.class);

        // 解释器
        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(new ElFunc());
        standardEvaluationContext.setBeanResolver(new BeanFactoryResolver(applicationContext));

        // 设置上下文内容, 使 el 可以获取占位符内容
        standardEvaluationContext.setVariable("num", num);
        // 设置内容
        Expression expression = spelExpressionParser
                .parseExpression("@elFunc.cardinalNumber(#num) and eqs(#num)");
        Object value = expression.getValue(standardEvaluationContext);
        System.out.println("@elFunc.cardinalNumber(#num) and eq(#num): " + value);
        return this;
    }

    public static void main(String[] args) {
        new ElParse().eqAndBeanContext(11);
        //new ElParse().addGetAndBeanContext(1).add().get().addGet(1);
    }
}
